package com.hqd.jjvm.rtda;

import com.hqd.jjvm.rtda.obj.JObject;
import com.hqd.jjvm.rtda.slot.NumberSlot;
import com.hqd.jjvm.rtda.slot.RefSlot;
import com.hqd.jjvm.rtda.slot.Slot;
import lombok.Getter;

@Getter
public class LocalVars {
    private Slot[] slots;

    public LocalVars(int size) {
        slots = new Slot[size];
    }

    public Float getFloatVal(int index) {
        NumberSlot numberSlot = (NumberSlot) slots[index];
        return numberSlot.getVal().floatValue();
    }

    public void setFloatVal(int index, Float val) {
        slots[index] = new NumberSlot(val);
    }

    public Long getLongVal(int index) {
        NumberSlot numberSlot = (NumberSlot) slots[index];
        return numberSlot.getVal().longValue();
    }

    public void setLongVal(int index, long val) {
        slots[index] = new NumberSlot(val);
        slots[index + 1] = null;
    }

    public Double getDoubleVal(int index) {
        NumberSlot numberSlot = (NumberSlot) slots[index];
        return numberSlot.getVal().doubleValue();
    }

    public void setDoubleVal(int index, Double val) {
        slots[index] = new NumberSlot(val);
        slots[index + 1] = null;
    }

    public Integer getIntVal(int index) {
        NumberSlot numberSlot = (NumberSlot) slots[index];
        return numberSlot.getVal().intValue();
    }

    public void setIntVal(int index, int val) {
        slots[index] = new NumberSlot(val);
    }

    public void setRefVal(int index, JObject ref) {
        slots[index] = new RefSlot(ref);
    }

    public <T extends JObject> T getRefVal(int index) {
        RefSlot refSlot = (RefSlot) slots[index];
        return (T) refSlot.getVal();
    }

    public Object getVal(int index) {
        return slots[index].getVal();
    }

    public void setVal(int i, Object val) {
        /**
         * 只有引用类型会为空
         */
        if (val instanceof JObject || val == null) {
            setRefVal(i, (JObject) val);
        } else {
            if (val instanceof Integer) {
                setIntVal(i, (Integer) val);
            } else if (val instanceof Float) {
                setFloatVal(i, (Float) val);
            } else if (val instanceof Long) {
                setLongVal(i, (Long) val);
            } else if (val instanceof Double) {
                setDoubleVal(i, (Double) val);
            } else {
                throw new RuntimeException("undefined type ");
            }
        }
    }

    public boolean getBoolVal(int index) {
        return getIntVal(index) == 0 ? false : true;
    }
}
